var listGroupSelectedIndex = -1
var listGroupItemHeight = 19
var listGroupColMarginWidth = 17
var listGroupColminWidth = 20

var listGroupToScroll = 0
/**
TODO : sauvegarde des informations (position des groupes et tailles)
*/

function listGroup(textarea)
{
	this.id = 0;
	
	this.onSelectChange = '';
	
	this.selectedIndex = -1;
	
	this.fields = new Array();
	this.groups = new Array();
	this.cache = new Array();
	this.drawed = new Array();
	this.fieldsIndex = new Array();
	this.groupsIndex = new Array();
	this.groupBox = false;
	this.showGroupBox = false;
	this.datasLength = 0;
	this.datasIndex = 0;

	this._tableElement = null;
	this._groupElements = new Array();
	this._groupElement = null;
	this._headElement = null;
	this._colsElement = null;
	this._colsElementList = new Array();
	this._dataElement = null;
	this._feetElement = null;
	this._buttonElement = null;
	this._containerElement = null;
	
	this.init(textarea)
}

listGroup.prototype.removeField = function(field, resize)
{
	if(this.fields.length<=1)return
	this._headElement.removeChild(this._headElement.childNodes[1+field*2]);
	this._colsElement.removeChild(this._colsElementList[this.fields[field].name]);
	this._colsElementList[field.name] = null;
	
	if(field<this.fields.length-1)
	{
		this._headElement.removeChild(this._headElement.childNodes[1+field*2]);
	}
	else if(field>0)
	{
		this._headElement.removeChild(this._headElement.childNodes[1+field*2-1]);
	}
	this.fields.splice(field, 1)
	this.fieldsIndex = new Array()
	for(var i=0; i<this.fields.length; i++)
	{
		this.fieldsIndex[this.fields[i].name] = i
	}
	
	if(resize==null || resize)
	{
		this.reSize()
	}
}

listGroup.prototype.moveField = function(field, newIndex)
{
	if(newIndex>=0)
	{
		var tmp = this.fields[field];
		this.fields.splice(field, 1)
		this.fields.splice((field<newIndex?newIndex-1:newIndex), 0, tmp)
		
		if(field<newIndex)
		{
			var counter = this._colsElementList[tmp.name].offsetLeft
			for(var i=field; i<newIndex; i++)
			{
				this._colsElementList[this.fields[i].name].style.left = counter+'px';
				var size = this.fields[i].width + 4
				if(i==0) size -= 2
				if(i==this.fields.length-1) size = size - 2 + 20
				counter+=size
				this._colsElementList[this.fields[i].name].style.width = size+'px';
			}
		}
		else
		{
			var counter = this._colsElementList[this.fields[newIndex+1].name].offsetLeft
			for(var i=newIndex; i<=field; i++)
			{
				this._colsElementList[this.fields[i].name].style.left = counter+'px';
				var size = this.fields[i].width + 4
				if(i==0) size -= 2
				if(i==this.fields.length-1) size = size - 2 + 20
				counter+=size
				this._colsElementList[this.fields[i].name].style.width = size+'px';
			}
		}
		
		if(newIndex<this.fields.length)
		{
			if(field<newIndex)
			{
				this._headElement.insertBefore(this._headElement.childNodes[1+field*2], this._headElement.childNodes[1+newIndex*2]);
				this._headElement.insertBefore(this._headElement.childNodes[1+field*2], this._headElement.childNodes[1+newIndex*2]);
			}
			else
			{
				this._headElement.insertBefore(this._headElement.childNodes[1+field*2-1], this._headElement.childNodes[1+newIndex*2]);
				this._headElement.insertBefore(this._headElement.childNodes[1+field*2], this._headElement.childNodes[1+newIndex*2]);
			}
		}
		else
		{
			this._headElement.insertBefore(this._headElement.childNodes[1+field*2+1], this._headElement.childNodes[1+this.fields.length*2-1]);
			this._headElement.insertBefore(this._headElement.childNodes[1+field*2], this._headElement.childNodes[1+this.fields.length*2-1]);
		}
		
		for(var j=0; j<this.fields.length; j++)
		{
			this.fieldsIndex[this.fields[j].name] = j
			if(j<this.fields.length-1)
			{
				this._headElement.childNodes[1+j*2+1].setAttribute("field", this.fields[j].name)
				if(this.fields[j].resizable)
				{
					var can = false;
					for(var k=j+1; k<this.fields.length; k++)
					{
						if(this.fields[k].resizable)
						{
							can = true;
							break;
						}
					}
					if(can)
					{
						this._headElement.childNodes[1+j*2+1].setAttribute("resizable", true)
					}
					else
					{
						this._headElement.childNodes[1+j*2+1].removeAttribute("resizable")
					}
				}
				else
				{
					this._headElement.childNodes[1+j*2+1].removeAttribute("resizable")
				}
				this._headElement.childNodes[1+j*2+1].className+=""
			}
		}
	}
}

listGroup.prototype.groupField = function(fieldIndex, index)
{
	if(this.fields.length<=1)return
	if(this.groups.length>=5)return
	var field = this.fields[fieldIndex];
	this.groups.splice(index, 0, field)
	this.removeField(fieldIndex, true)
	
	var elem = document.createElement("TABLE")
	elem.className = "listgroup_field_group"
	elem.cellSpacing="0px";
	elem.cellPadding="0px";
	
	var r = elem.insertRow(0);
	r.setAttribute("valign", "top")
	var c = r.insertCell(0);
	c.setAttribute("field", field.name)
	c.className = "listgroup_field_group_label"
	c.innerHTML = "<div><label>"+field.label+"</label></div>"
	var c = r.insertCell(1);
	c.setAttribute("field", field.name)
	c.className = "listgroup_field_group_button"
	c.innerHTML = '<div><div order="asc"></div></div>'
	var c = r.insertCell(2);
	c.className = "listgroup_field_group_subs"
	c.innerHTML = ''
	
	if(this._groupElements.length==0)
	{
		this._groupElement.appendChild(elem)
	}
	else if(index>=this._groupElements.length)
	{
		var last = this._groupElements[this._groupElements.length-1]
		last.rows[0].cells[2].innerHTML = '<div class="listgroup_field_group_sub"></div>';
		last.rows[0].cells[2].appendChild(elem)
	}
	else if(index==0)
	{
		elem.rows[0].cells[2].innerHTML = '<div class="listgroup_field_group_sub"></div>';
		elem.rows[0].cells[2].appendChild(this._groupElements[0])
		this._groupElement.appendChild(elem)
	}
	else
	{
		elem.rows[0].cells[2].innerHTML = '<div class="listgroup_field_group_sub"></div>';
		elem.rows[0].cells[2].appendChild(this._groupElements[index])
		this._groupElements[index-1].rows[0].cells[2].appendChild(elem)
		this._groupElement.appendChild(elem)
	}
	
	this._groupElements.splice(index, 0, elem)
	this._containerElement.setAttribute("groupitems", this._groupElements.length)
	this._containerElement.className+=""
	this.reSize()
	
	this.groupsIndex = new Array()
	for(var i=0; i<this.groups.length; i++)
	{
		this.groupsIndex[this.groups[i].name] = i
	}
}

listGroup.prototype.removeGroup = function(field)
{
	if(this.groups.length==0)return
	if(this.groups.length == 1)
	{
		this._groupElement.removeChild(this._groupElements[0])
	}
	else if(field == 0)
	{
		this._groupElement.removeChild(this._groupElements[0])
		this._groupElement.appendChild(this._groupElements[1])
	}
	else if(field == this.groups.length-1)
	{
		this._groupElements[field-1].rows[0].cells[2].innerHTML = ""
	}
	else
	{
		this._groupElements[field-1].rows[0].cells[2].removeChild(this._groupElements[field])
		this._groupElements[field-1].rows[0].cells[2].appendChild(this._groupElements[field+1])
	}
	
	this.groups.splice(field, 1)
	this._groupElements.splice(field, 1)
	this._containerElement.setAttribute("groupitems", this._groupElements.length)
	this._containerElement.className+=""

	this.groupsIndex = new Array()
	for(var i=0; i<this.groups.length; i++)
	{
		this.groupsIndex[this.groups[i].name] = i
	}
}

listGroup.prototype.moveGroup = function(field, newIndex)
{
	if(this.groups.length<=1) return
	if(newIndex == 0)
	{	
		if(field == this.groups.length-1)
		{
			this._groupElements[field-1].rows[0].cells[2].innerHTML = ""
			this._groupElements[field].rows[0].cells[2].innerHTML = '<div class="listgroup_field_group_sub"></div>';
		}
		else
		{
			this._groupElements[field-1].rows[0].cells[2].removeChild(this._groupElements[field])
			this._groupElements[field-1].rows[0].cells[2].appendChild(this._groupElements[field+1])
		}
		this._groupElements[field].rows[0].cells[2].appendChild(this._groupElements[0])
		this._groupElement.appendChild(this._groupElements[field])
	}
	else
	{
		if(field == 0)
		{
			this._groupElement.removeChild(this._groupElements[field])
			this._groupElement.appendChild(this._groupElements[field+1])
		}
		else if(field == this.groups.length-1)
		{
			this._groupElements[field-1].rows[0].cells[2].innerHTML = ""
			this._groupElements[field].rows[0].cells[2].innerHTML = '<div class="listgroup_field_group_sub"></div>';
		}
		else
		{
			this._groupElements[field-1].rows[0].cells[2].removeChild(this._groupElements[field])
			this._groupElements[field-1].rows[0].cells[2].appendChild(this._groupElements[field+1])
		}
		
		if(newIndex<this.groups.length)
		{
			this._groupElements[newIndex-1].rows[0].cells[2].removeChild(this._groupElements[newIndex])
			this._groupElements[field].rows[0].cells[2].appendChild(this._groupElements[newIndex])
			this._groupElements[newIndex-1].rows[0].cells[2].appendChild(this._groupElements[field])
		}
		else
		{
			this._groupElements[field].rows[0].cells[2].innerHTML = '';
			this._groupElements[newIndex-1].rows[0].cells[2].innerHTML = '<div class="listgroup_field_group_sub"></div>';
			this._groupElements[newIndex-1].rows[0].cells[2].appendChild(this._groupElements[field])
		}
	}
	var tmp = this.groups[field];
	this.groups.splice(field, 1)
	this.groups.splice((field<newIndex?newIndex-1:newIndex), 0, tmp)
	var tmp = this._groupElements[field];
	this._groupElements.splice(field, 1)
	this._groupElements.splice((field<newIndex?newIndex-1:newIndex), 0, tmp)

	this.groupsIndex = new Array()
	for(var i=0; i<this.groups.length; i++)
	{
		this.groupsIndex[this.groups[i].name] = i
	}
}

listGroup.prototype.fieldGroup = function(fieldIndex, index)
{
	var field = this.groups[fieldIndex];
	this.fields.splice(index, 0, field)
	this.removeGroup(fieldIndex)
	
	if(index == this.fields.length-1)
	{
		var resizable = false
		if(this.fields[index-1].resizable)
		{
			for(var k=index-1; k<this.fields.length; k++)
			{
				if(this.fields[k].resizable)
				{
					resizable = true;
					break;
				}
			}
		}
	
		var elem = document.createElement("DIV")
		if(resizable)
		{
			elem.setAttribute("resizable", "true")
		}
		elem.className = "listgroup_field_head"
		elem.setAttribute("field", field.name)
		elem.title = "trier par : "+field.label
		elem.innerHTML = '<div class="listgroup_field_sort">&nbsp;</div><div class="listgroup_field_content">'+(field.content==''?field.label:field.content)+'</div>'
		elem.childNodes[1].style.width = (field.width-listGroupColMarginWidth)+"px"
		elem.style.width = (field.width)+"px"
		this._headElement.insertBefore(elem, this._headElement.childNodes[1+index*2-1])

		var elem = document.createElement("DIV")
		if(resizable)
		{
			elem.setAttribute("resizable", "true")
		}
		elem.className = "listgroup_separator"
		elem.setAttribute("field", this.fields[index-1].name)
		elem.innerHTML = "<div></div>"
		this._headElement.insertBefore(elem, this._headElement.childNodes[1+index*2-1])
		
		this._colsElement.appendChild(this._colsElementList[field.name])
		this._colsElementList[field.name].scrollTop = this._scrollElement.scrollTop
	}
	else
	{
		var resizable = false
		if(field.resizable)
		{
			for(var k=index; k<this.fields.length; k++)
			{
				if(this.fields[k].resizable)
				{
					resizable = true;
					break;
				}
			}
		}
	
		var elem = document.createElement("DIV")
		if(resizable)
		{
			elem.setAttribute("resizable", "true")
		}
		elem.className = "listgroup_separator"
		elem.setAttribute("field", field.name)
		elem.innerHTML = "<div></div>"
		this._headElement.insertBefore(elem, this._headElement.childNodes[1+index*2])
	
		var elem = document.createElement("DIV")
		if(resizable)
		{
			elem.setAttribute("resizable", "true")
		}
		elem.className = "listgroup_field_head"
		elem.setAttribute("field", field.name)
		elem.title = "trier par : "+field.label
		elem.innerHTML = '<div class="listgroup_field_sort">&nbsp;</div><div class="listgroup_field_content">'+(field.content==''?field.label:field.content)+'</div>'
		elem.childNodes[1].style.width = (field.width-listGroupColMarginWidth)
		elem.style.width = (field.width)
		this._headElement.insertBefore(elem, this._headElement.childNodes[1+index*2])
		
		this._colsElement.appendChild(this._colsElementList[field.name])
	}
	this._groupElements.splice(fieldIndex, 0)
	this._containerElement.setAttribute("groupitems", this._groupElements.length)
	this._containerElement.className+=""
	this.reSize()
	
	this.fieldsIndex = new Array()
	for(var i=0; i<this.fields.length; i++)
	{
		this.fieldsIndex[this.fields[i].name] = i
	}
}

listGroup.prototype.reSize = function()
{
	var fields_undefined = new Array();
	var fixSize = (this.fields.length-1)*4; //taille des separateurs
	fixSize+=Math.max(0, this._groupElements.length-1)*16 // le blanc quand il y a plusieurs groupes
	var moveSize = 0;
	for(var i=0; i<this.fields.length; i++)
	{
		var field = this.fields[i];
		if(field.resizable)
		{
			fields_undefined.push(i)
			moveSize+=field.width
		}
		else
		{
			fixSize+=field.width
		}
	}

	if(fields_undefined.length>0)
	{
		var aviable = this._headElement.offsetWidth - 19 - fixSize;
		var done=0
		for(var i=0; i<fields_undefined.length; i++)
		{
			var w = Math.max(listGroupColminWidth, Math.floor(this.fields[fields_undefined[i]].width*aviable/moveSize))
			done+=w
			this.fields[fields_undefined[i]].width = w
		}
		var rest = this._headElement.offsetWidth - 19 - fixSize - done;
		for(var i=0; i<fields_undefined.length && rest!=0; i++)
		{
			var s = Math.min(this.fields[fields_undefined[i]].width-listGroupColminWidth, rest)
			rest-=s
			this.fields[fields_undefined[i]].width += s
		}
	}
	var w_head = (this.fields.length-1)*4 + Math.max(0, this._groupElements.length-1)*16
	var counter = Math.max(0, this._groupElements.length-1)*16
	
	for(var i=0; i<this.fields.length; i++)
	{
		w_head+=this.fields[i].width
		this._headElement.childNodes[1+i*2].childNodes[1].style.width = (this.fields[i].width-listGroupColMarginWidth)+'px';
		this._headElement.childNodes[1+i*2].style.width = (this.fields[i].width)+'px';
		
		this._colsElementList[this.fields[i].name].style.left = counter+'px';
		var size = this.fields[i].width + 4
		if(i==0) size -= 2
		if(i==this.fields.length-1) size = size - 2 + 20
		counter+=size
		this._colsElementList[this.fields[i].name].style.width = size+'px';
	}
	this._headElement.childNodes[1+this.fields.length*2-1].style.width = (this._headElement.offsetWidth - w_head)+"px";
}
listGroup.prototype.initSize = function()
{
	var fields_defined = new Array();
	var fields_undefined = new Array();
	var size = (this.fields.length-1)*4; //taille des separateurs
	for(var i=0; i<this.fields.length; i++)
	{
		var field = this.fields[i];
		if(!field.resizable)
		{
			this.fields[i].width = (isNaN(field.width)?20:field.width);
			size+=(isNaN(field.width)?20:field.width)
		}
		else if(!isNaN(field.width))
		{
			fields_defined.push(i)
			this.fields[i].width = field.width;
			size+=field.width
		}
		else
		{
			fields_undefined.push(i)
		}
	}
	if(fields_undefined.length>0)
	{
		var avaible = this._headElement.offsetWidth - 19 - size;
		var missing = (10*fields_undefined.length)-avaible
		if(missing>0)
		{
			for(var i=0; i<fields_undefined.length; i++)
			{
				this.fields[fields_undefined[i]].width = listGroupColminWidth;
			}
			var s = Math.floor(missing/fields_defined.length)
			for(var i=1; i<fields_defined.length; i++)
			{
				this.fields[fields_defined[i]].width -= s;
			}
			this.fields[fields_defined[0]].width -= (missing-((fields_defined.length-1)*s));
			
		}
		else
		{
			var s = Math.floor(avaible/fields_undefined.length)
			for(var i=1; i<fields_undefined.length; i++)
			{
				this.fields[fields_undefined[i]].width = s;
			}
			this.fields[fields_undefined[0]].width = (avaible-((fields_undefined.length-1)*s));
		}
	}
	var counter = Math.max(0, this._groupElements.length-1)*16
	for(var i=0; i<this.fields.length; i++)
	{
		this._headElement.childNodes[1+i*2].childNodes[1].style.width = (this.fields[i].width-listGroupColMarginWidth)+'px';
		this._headElement.childNodes[1+i*2].style.width = (this.fields[i].width)+'px';
		this._colsElementList[this.fields[i].name].style.left = counter+'px';
		var size = this.fields[i].width + 4
		if(i==0) size -= 2
		if(i==this.fields.length-1) size = size - 2 + 20
		counter+=size
		this._colsElementList[this.fields[i].name].style.width = size+'px';
	}
	
	this._innerScrollElement.style.height = (this.datasLength*listGroupItemHeight)+"px"
	for(var i=0; i<this.fields.length; i++)
	{
		this._colsElementList[this.fields[i].name].innerHTML='<div class="listgroup_field_data" style="visibility:hidden; top:'+(this.datasLength*listGroupItemHeight)+'px"></div>'
	}
	if(this._innerScrollElement.offsetHeight > this._scrollElement.offsetHeight)
	{
		this._scrollElement.style.visibility="visible"
	}
}

listGroup.prototype.init = function(textarea)
{
	var ch = null;
	eval('ch='+textarea.value);
	this.id = ch.id;
	this.fields = ch.fields;
	this.order = ch.order;
	this.groupBox = ch.groupBox;
	this.onSelectChange = ch.onSelectChange;
	this.showGroupBox = ch.showGroupBox;
	this.datasLength = ch.datasLength;
	this.datasIndex = 0;
	
	ch = null;
	this.initElements(textarea)
	this.initHandlers()
}

listGroup.prototype.initElements = function(textarea)
{
	textarea.style.display = 'none'
	
	this._containerElement = document.createElement("DIV");
	this._containerElement.className = "listgroup_box"
	if(document.all)
	{
		this._containerElement.setAttribute("browser", "IE")
	}
	textarea.parentNode.insertBefore(this._containerElement, textarea)
	if(this.groupBox)
	{
		this._containerElement.setAttribute('groupbox', true)
	}
	if(this.showGroupBox)
	{
		this._groupElement = document.createElement("DIV");
		this._groupElement.className = "listgroup_area_group"
		this._groupElement.innerHTML = ''
		this._containerElement.appendChild(this._groupElement)
	
	
		this._buttonElement = document.createElement("DIV");
		this._buttonElement.className = "listgroup_button_groups"
		this._containerElement.appendChild(this._buttonElement)
	}

	this.fields = this.fields.sort(function(a, b)
	{
		if(a.index<b.index) return -1
		if(a.index>b.index) return 1
		if(a.name<b.name) return -1
		if(a.name>b.name) return 1
		return 0;
	})
	var ch_cols = new Array();
	var ch_head = new Array();
	ch_head.push('<div field="'+this.fields[0].name+'" class="listgroup_field_space"></div>')
	this.fieldsIndex = new Array();
	for(var i=0; i<this.fields.length; i++)
	{
		var field = this.fields[i]
		this.fieldsIndex[field.name] = i;
		
		var resizable = false
		if(field.resizable)
		{
			for(var k=i+1; k<this.fields.length; k++)
			{
				if(this.fields[k].resizable)
				{
					resizable = true;
					break;
				}
			}
		}
		
		if(resizable)
		{
			ch_head.push('<div resizable="true" ')
		}
		else
		{
			ch_head.push('<div ')
		}
		ch_cols.push('<div class="listgroup_field_col"></div>')
		ch_head.push('class="listgroup_field_head" field="'+field.name+'" title="trier par : '+field.label+'">')
		ch_head.push('<div class="listgroup_field_sort">&nbsp;</div><div class="listgroup_field_content">'+(field.content==''?field.label:field.content)+'</div>')
		ch_head.push('</div>')
		if(i<this.fields.length-1)
		{
			if(resizable)
			{
				ch_head.push('<div resizable="true" ')
			}
			else
			{
				ch_head.push('<div ')
			}
			
			ch_head.push('field="'+field.name+'" class="listgroup_separator"><div></div></div>')
		}
	}
	ch_head.push('<div field="'+this.fields[this.fields.length-1].name+'" class="listgroup_field_headrest" style="width:19px"></div>')
	
	this._headElement = document.createElement("DIV");
	this._headElement.className = "listgroup_area_head"
	this._headElement.innerHTML = ch_head.join('')
	this._containerElement.appendChild(this._headElement)
	this._dataElement = document.createElement("DIV");
	this._dataElement.className = "listgroup_area_data"
	this._containerElement.appendChild(this._dataElement)
	
	this._overElement = document.createElement("DIV");
	this._overElement.className = "listgroup_area_over"
	this._overElement.style.visibility="hidden"
	this._dataElement.appendChild(this._overElement)

	this._selectElement = document.createElement("DIV");
	this._selectElement.className = "listgroup_area_select"
	this._selectElement.style.visibility="hidden"
	this._dataElement.appendChild(this._selectElement)
	
	
	this._scrollElement = document.createElement("DIV");
	this._scrollElement.className = "listgroup_area_scroll"
	this._scrollElement.style.visibility="hidden"
	this._dataElement.appendChild(this._scrollElement)

	this._innerScrollElement = document.createElement("DIV");
	this._scrollElement.appendChild(this._innerScrollElement)
	
	this._colsElement = document.createElement("DIV");
	this._colsElement.className = "listgroup_area_cols"
	this._colsElement.innerHTML = ch_cols.join('')
	this._dataElement.appendChild(this._colsElement)
	
	for(var i=0; i<this.fields.length; i++)
	{
		var field = this.fields[i]
		this._colsElementList[field.name] = this._colsElement.childNodes[i];
	}

	this.initSize();

	this._feetElement = document.createElement("DIV");
	this._feetElement.className = "listgroup_area_feet"
	this._feetElement.innerHTML = "listgroup_area_feet"
	this._containerElement.appendChild(this._feetElement)
	
	if(this.order.length>0)
	{
		for(var j=0; j<this.fields.length; j++)
		{
			var field = this.fields[j]
			this._colsElementList[field.name].innerHTML='<div class="listgroup_field_data" style="top:'+(this.datasLength*listGroupItemHeight)+'px"></div>'
			this._colsElementList[field.name].removeAttribute("selected")
		}
			
		var fieldName = this.order[0].name;
		this._colsElementList[fieldName].setAttribute("selected", true)
		this._colsElement.className+=""
		
		this._headElement.childNodes[1+2*this.fieldsIndex[fieldName]].childNodes[0].setAttribute("order", this.order[0].sens)
		this._headElement.childNodes[1+2*this.fieldsIndex[fieldName]].className+=""
	}
	
	this.displayDatas();
}

listGroup.prototype.initHandlers = function()
{
	var thisObject = this;
	
	var fctResize = function()
	{
		thisObject.reSize();
	}
	
	if (window.HTMLElement)
	{
		window.addEventListener("resize", fctResize, false);
	}
	else
	{
		window.attachEvent("onresize", fctResize);
	}
	
	this._scrollElement.onscroll = function(e)
	{
		var scrollTop = thisObject._scrollElement.scrollTop;
		thisObject.datasIndex = Math.floor(scrollTop/listGroupItemHeight);
		clearTimeout(listGroupToScroll)
		listGroupToScroll = setTimeout(function()
		{
			thisObject.displayDatas()
		}, 100);
		for(var j=0; j<thisObject.fields.length; j++)
		{
			var field = thisObject.fields[j]
			thisObject._colsElementList[field.name].scrollTop = scrollTop;
		}
		thisObject._selectElement.style.top=(thisObject.selectedIndex * listGroupItemHeight - scrollTop)+"px"
	}
	
	var listGroupWheel = function(delta)
	{
		thisObject._scrollElement.scrollTop+=delta*42
	}
	if (window.HTMLElement)
	{
		this._colsElement.addEventListener('DOMMouseScroll', function(e)
		{
			listGroupWheel(e.detail/3)
		}, false);
	}
	else
	{
		this._dataElement.onmousewheel = function()
		{
			if(window.opera)
			{
				listGroupWheel(event.wheelDelta/120)
			}
			else
			{
				listGroupWheel(-event.wheelDelta/120)
			}
		}
	}
	
	this._colsElement.onmouseout = function(e)
	{
		thisObject._overElement.style.visibility="hidden"
	}
	this._colsElement.onmousemove = function(e)
	{
		if(window.event)
		{
			var target = window.event.srcElement;
			var pos = [window.event.clientX, window.event.clientY]
		}
		else
		{
			var target = e.target
			var pos = [e.clientX, e.clientY] 
		}
		if(thisObject._dataElement.posBox == null)
		{
			thisObject._dataElement.posBox = Position.get(thisObject._dataElement)
		}
		pos[0]-=thisObject._dataElement.posBox.left
		pos[1]-=thisObject._dataElement.posBox.top
		var index = Math.floor((pos[1]+thisObject._scrollElement.scrollTop)/listGroupItemHeight)
		if(index<thisObject.datasLength)
		{
			thisObject._overElement.style.visibility="visible"
			thisObject._overElement.style.top=(index * listGroupItemHeight - thisObject._scrollElement.scrollTop)+"px"
		}
		else
		{
			thisObject._overElement.style.visibility="hidden"
		}
	}
	this._colsElement.onclick = function(e)
	{
		if(window.event)
		{
			var target = window.event.srcElement;
			var pos = [window.event.clientX, window.event.clientY]
		}
		else
		{
			var target = e.target
			var pos = [e.clientX, e.clientY] 
		}
		if(thisObject._dataElement.posBox == null)
		{
			thisObject._dataElement.posBox = Position.get(thisObject._dataElement)
		}
		pos[0]-=thisObject._dataElement.posBox.left
		pos[1]-=thisObject._dataElement.posBox.top
		var index = Math.floor((pos[1]+thisObject._scrollElement.scrollTop)/listGroupItemHeight)
		if(thisObject.selectedIndex!=index)
		{
			thisObject.selectedIndex = index
			if(thisObject.selectedIndex<thisObject.datasLength)
			{
				thisObject._selectElement.style.visibility="visible"
				thisObject._selectElement.style.top=(thisObject.selectedIndex * listGroupItemHeight - thisObject._scrollElement.scrollTop)+"px"
				if(thisObject.cache[thisObject.selectedIndex] != null)
				{
					if(thisObject.onSelectChange != '')
					{
						var fct = eval(thisObject.onSelectChange)
						fct(thisObject.cache[thisObject.selectedIndex])
					}
				}
			}
		}
	}
	
	this._headElement.onmousedown = function(e)
	{
		if(window.event)
		{
			var target = window.event.srcElement;
			var pos = [window.event.clientX, window.event.clientY]
		}
		else
		{
			var target = e.target
			var pos = [e.clientX, e.clientY] 
		}
		while(target!=null)
		{
			if(target.tagName=="DIV" && target.getAttribute("field")!=null)
			{
				break;
			}
			target = target.parentNode;
		}
		if(target==null) return
		if(target.tagName=="DIV" && target.className=="listgroup_separator")
		{
			var i = thisObject.fieldsIndex[target.getAttribute("field")]
			if(target.getAttribute("resizable") == null)
			{
				return
			}
			if(thisObject._resizeLeftElement == null)
			{
				thisObject._resizeLeftElement = document.createElement("DIV");
				thisObject._resizeLeftElement.className = "listgroup_resizebar"
				thisObject._containerElement.appendChild(thisObject._resizeLeftElement)
				
				thisObject._resizeRightElement = document.createElement("DIV");
				thisObject._resizeRightElement.className = "listgroup_resizebar"
				thisObject._containerElement.appendChild(thisObject._resizeRightElement)
			}
			else
			{
				thisObject._resizeLeftElement.style.display = "block"
				thisObject._resizeRightElement.style.display = "block"
			}
			thisObject._resizeLeftElement.style.left = Math.max(-1, thisObject._headElement.childNodes[1+i*2].offsetLeft-3)+"px"
			thisObject._resizeRightElement.style.left = (thisObject._headElement.childNodes[1+i*2].offsetLeft + thisObject.fields[i].width + 1)+"px"
			
			var rest  = thisObject.fields[i].width
			for(var j=i+1; j<thisObject.fields.length; j++)
			{
				if(thisObject.fields[j].resizable)
				{
					rest+=(thisObject.fields[j].width - listGroupColminWidth)
				}
			}

			var dragingPos =  pos
			var dragingLimit =  [listGroupColminWidth, rest]
			var dragingField =  target.getAttribute("field")
			
			target.setCapture();
			target.setAttribute("dragging", true)
			target.onmouseup = function(e)
			{
				if(this.getAttribute('dragging') == null)
				{
					return
				}
				this.removeAttribute('dragging')
				this.releaseCapture();
				
				if(window.event)
				{
					var pos = [window.event.clientX, window.event.clientY] 
				}
				else
				{
					var pos = [e.clientX, e.clientY] 
				}
				var i = thisObject.fieldsIndex[dragingField]
				var w = Math.max(dragingLimit[0], Math.min(dragingLimit[1], thisObject.fields[i].width + (pos[0]-dragingPos[0])))
				
				var diff = w - thisObject.fields[i].width;
				var size = 0
				for(var j=i+1; j<thisObject.fields.length; j++)
				{
					if(thisObject.fields[j].resizable)
					{
						size+=thisObject.fields[j].width
					}
				}
				if(size>0)
				{
					thisObject.fields[i].width += diff;
					var done=0
					for(var j=i+1; j<thisObject.fields.length; j++)
					{
						if(thisObject.fields[j].resizable)
						{
							var s = Math.min(thisObject.fields[j].width-listGroupColminWidth, Math.floor(thisObject.fields[j].width*diff/size))
							done+=s
							thisObject.fields[j].width -= s
						}
					}
					diff-=done
					for(var j=i+1; j<thisObject.fields.length && diff!=0; j++)
					{
						var s = Math.min(thisObject.fields[j].width-listGroupColminWidth, diff)
						diff-=s
						thisObject.fields[j].width -= s
					}
					var counter = thisObject._colsElementList[thisObject.fields[i].name].offsetLeft
					for(var j=i; j<thisObject.fields.length; j++)
					{
						thisObject._colsElementList[thisObject.fields[j].name].style.left = counter+'px';
						
						var size = thisObject.fields[j].width
						thisObject._headElement.childNodes[1+j*2].childNodes[1].style.width = (size-listGroupColMarginWidth) +'px';
						thisObject._headElement.childNodes[1+j*2].style.width = (size) +'px';
						size+=4
						if(j==0) size -=2
						if(j == thisObject.fields.length-1) size = size - 2 + 20
						counter+=size
						
						thisObject._colsElementList[thisObject.fields[j].name].style.width = size+'px';
					}
				}
				
				this.onmousemove = null;
				thisObject._resizeLeftElement.style.display = "none"
				thisObject._resizeRightElement.style.display = "none"
				
			}
			target.onmousemove = function(e)
			{
				if(window.event)
				{
					var pos = [window.event.clientX, window.event.clientY] 
				}
				else
				{
					var pos = [e.clientX, e.clientY] 
				}
				
				var i = thisObject.fieldsIndex[dragingField]
				var w = Math.max(dragingLimit[0], Math.min(dragingLimit[1], thisObject.fields[i].width + (pos[0]-dragingPos[0])))
				thisObject._resizeRightElement.style.left = (thisObject._headElement.childNodes[1+i*2].offsetLeft + w + 1)+"px"
			}
		}
		else if(target.tagName=="DIV" && (target.className=="listgroup_field_head" || target.className=="listgroup_field_headrest" || target.className=="listgroup_field_space"))
		{
			if(target.className == "listgroup_field_headrest")
			{
				if(thisObject.fields.length == 0) return
				target = thisObject._headElement.childNodes[1+(thisObject.fields.length-1)*2]
			}
			else if(target.className == "listgroup_field_space")
			{
				if(thisObject.fields.length == 0) return
				target = thisObject._headElement.childNodes[1]
			}
			target.setAttribute('pressed', true)
			target.className+=""
			if(target.previousSibling.className=="listgroup_field_space")
			{
				target.previousSibling.setAttribute('pressed', true)
				target.previousSibling.className+=""
			}
			
			var i = thisObject.fieldsIndex[target.getAttribute("field")]
			
			var dragingPos = pos
			thisObject.dragingMode = null
			
			target.setCapture();
			target.setAttribute("dragging", true)
			target.onmousemove = function(e)
			{
				var i = thisObject.fieldsIndex[this.getAttribute("field")]
				if(window.event)
				{
					var pos = [window.event.clientX, window.event.clientY] 
				}
				else
				{
					var pos = [e.clientX, e.clientY] 
				}
				if(thisObject.dragingMode == null)
				{
					if(Math.abs(dragingPos[0]-pos[0])>5 || Math.abs(dragingPos[1]-pos[1])>5)
					{
						thisObject.dragingMode = "move"
						if(thisObject._moveElement == null)
						{
							thisObject._crossElement = document.createElement("DIV");
							thisObject._crossElement.className = "listgroup_cross"
							thisObject._crossElement.style.display="none"
							thisObject._containerElement.appendChild(thisObject._crossElement)
							
							thisObject._arrowsElement = document.createElement("DIV");
							thisObject._arrowsElement.className = "listgroup_arrows"
							thisObject._arrowsElement.style.display="none"
							thisObject._containerElement.appendChild(thisObject._arrowsElement)
							
							thisObject._moveElement = document.createElement("DIV");
							thisObject._moveElement.className = "listgroup_movebar"
							thisObject._containerElement.appendChild(thisObject._moveElement)
						}
						else
						{
							thisObject._crossElement.style.display="none"
							thisObject._arrowsElement.style.display="none"
							thisObject._moveElement.style.display="block"
						}
						this.dragingPosDiff = [pos[0]-thisObject._headElement.childNodes[1+i*2].offsetLeft, pos[1]-thisObject._headElement.offsetTop]
			
						var size = 0;
						this.dragingHeadAreas = new Array() 
						for(var j=0; j<thisObject.fields.length; j++)
						{
							var middle = Math.round(thisObject.fields[j].width/2)
							if(j!=i && j!=i+1)
							{
								this.dragingHeadAreas.push([j, (j==0?-9999:size), size+middle, (j==0?size-1:size-3)])
							}
							if(j!=i && j!=i-1)
							{
								this.dragingHeadAreas.push([j+1, size+middle, (j==thisObject.fields.length-1?size+9999:size+4+thisObject.fields[j].width), (j==thisObject.fields.length-1?thisObject._headElement.offsetWidth:size+thisObject.fields[j].width+1)])
							}
							size+=thisObject.fields[j].width+4
						}

						var size = 0;
						this.dragingGroupAreas = new Array() 
						for(var j=0; j<thisObject.groups.length; j++)
						{
							var width = (thisObject._groupElements[j].rows[0].cells[0].offsetWidth+35)
							var middle = Math.round(width/2)
							this.dragingGroupAreas.push([j, (j==0?-9999:size+4), size+4+middle, (j==0?size+4:size+9)])
							this.dragingGroupAreas.push([j+1, size+4+middle, (j==thisObject.groups.length-1?size+9999:size+9+width), size+9+width])
							size+=width
						}
			
						thisObject._moveElement.style.top = thisObject._headElement.offsetTop+"px"
						thisObject._moveElement.style.left = thisObject._headElement.childNodes[1+i*2].offsetLeft+"px"
						thisObject._moveElement.style.width = thisObject._headElement.childNodes[1+i*2].offsetWidth+"px"
						thisObject._moveElement.innerHTML = (thisObject.fields[i].content==''?thisObject.fields[i].label:thisObject.fields[i].content)
						
						thisObject._headElement
					}
					return
				}
				else if(thisObject.dragingMode == "move")
				{
					var l = (pos[0]-this.dragingPosDiff[0])
					var t = (pos[1]-this.dragingPosDiff[1])
					if(l < 0-thisObject._moveElement.offsetWidth
						|| l > thisObject._headElement.offsetWidth
						|| t < 0-thisObject._moveElement.offsetHeight
						|| t > thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
					)
					{
						thisObject._crossElement.style.left = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2 - 20)+"px"
						thisObject._crossElement.style.top = (pos[1]-this.dragingPosDiff[1] + thisObject._moveElement.offsetHeight/2 - 20)+"px"
						thisObject._crossElement.style.display = "block"
						
						thisObject._arrowsElement.style.display = "none"
					}
					else if(t >= thisObject._headElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._headElement.offsetWidth
					)
					{
						var find = false;
						var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
						for(var j=0; j<this.dragingHeadAreas.length; j++)
						{
							if(middle>=this.dragingHeadAreas[j][1] && middle<=this.dragingHeadAreas[j][2])
							{
								thisObject._arrowsElement.style.left = (this.dragingHeadAreas[j][3]-4)+"px"
								thisObject._arrowsElement.style.top = "";
								thisObject._arrowsElement.style.display = "block"
								find = true;
								break
							}
						}
						if(!find)
						{
							thisObject._arrowsElement.style.display = "none"
						}
						thisObject._crossElement.style.display = "none"
					}
					else if(thisObject._containerElement.getAttribute('groupbox') !=null
						&& t >= thisObject._groupElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._groupElement.offsetHeight + thisObject._groupElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._groupElement.offsetWidth
					)
					{
						if(thisObject.groups.length==0)
						{
							thisObject._arrowsElement.style.top = "1px"
							thisObject._arrowsElement.style.left = "4px"
							thisObject._arrowsElement.style.display = "block"
						}
						else
						{
							var find = false;
							var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
							for(var j=0; j<this.dragingGroupAreas.length; j++)
							{
								if(middle>=this.dragingGroupAreas[j][1] && middle<=this.dragingGroupAreas[j][2])
								{
									thisObject._arrowsElement.style.left = (this.dragingGroupAreas[j][3]-4)+"px"
									thisObject._arrowsElement.style.top = (this.dragingGroupAreas[j][0]*9-5)+(this.dragingGroupAreas[j][0]==0?4:0)+"px";
									thisObject._arrowsElement.style.display = "block"
									find = true;
									break
								}
							}
							if(!find)
							{
								thisObject._arrowsElement.style.display = "none"
							}
							thisObject._crossElement.style.display = "none"
						}
					}
					else
					{
						thisObject._crossElement.style.display = "none"
						thisObject._arrowsElement.style.display = "none"
					}
					thisObject._moveElement.style.left = l+"px"
					thisObject._moveElement.style.top = t+"px"
				}
			}
			target.onmouseup = function(e)
			{
				if(window.event)
				{
					var pos = [window.event.clientX, window.event.clientY] 
				}
				else
				{
					var pos = [e.clientX, e.clientY]
				}
				
				if(this.getAttribute('dragging') == null)
				{
					return
				}
				this.removeAttribute('dragging')
				this.releaseCapture();
				
				this.removeAttribute('pressed')
				this.className+=""
				if(this.previousSibling.className=="listgroup_field_space")
				{
					this.previousSibling.removeAttribute('pressed')
					this.previousSibling.className+=""
				}
				
				this.onmousemove = null;
				if(thisObject.dragingMode=="move")
				{
					thisObject.dragingMode == null
					var i = thisObject.fieldsIndex[this.getAttribute("field")]
					var l = (pos[0]-this.dragingPosDiff[0])
					var t = (pos[1]-this.dragingPosDiff[1])
					if(l < 0-thisObject._moveElement.offsetWidth
						|| l > thisObject._headElement.offsetWidth
						|| t < 0-thisObject._moveElement.offsetHeight
						|| t > thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
					)
					{
						thisObject.removeField(i)
					}
					else if(t >= thisObject._headElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._headElement.offsetWidth
					)
					{
						var find = -1;
						var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
						for(var j=0; j<this.dragingHeadAreas.length; j++)
						{
							if(middle>=this.dragingHeadAreas[j][1] && middle<=this.dragingHeadAreas[j][2])
							{
								find = this.dragingHeadAreas[j][0];
								break
							}
						}
						if(find!=-1)
						{
							thisObject.moveField(i, find)
						}
					}
					else if(thisObject._containerElement.getAttribute('groupbox') !=null
						&& t >= thisObject._groupElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._groupElement.offsetHeight + thisObject._groupElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._groupElement.offsetWidth
					)
					{
						if(thisObject.groups.length==0)
						{
							thisObject.groupField(i, 0)
						}
						else
						{
							var find = -1;
							var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
							for(var j=0; j<this.dragingGroupAreas.length; j++)
							{
								if(middle>=this.dragingGroupAreas[j][1] && middle<=this.dragingGroupAreas[j][2])
								{
									find = this.dragingGroupAreas[j][0];
									break
								}
							}
							if(find!=-1)
							{
								thisObject.groupField(i, find)
							}
						}
					}
					else
					{
					}

					thisObject._moveElement.style.display="none"
					thisObject._crossElement.style.display="none"
					thisObject._arrowsElement.style.display="none"
				}
				else
				{
					thisObject.dragingMode == null
					var i = thisObject.fieldsIndex[this.getAttribute("field")]
					thisObject.sortDatas(thisObject.fields[i].name)				
				}
			}		
		}
	}
	if(this.showGroupBox)
	{
		this._buttonElement.onclick = function()
		{
			if(thisObject._containerElement.getAttribute('groupbox')==null)
			{
				thisObject._containerElement.setAttribute('groupbox', true)
			}
			else
			{
				thisObject._containerElement.removeAttribute('groupbox')
			}
			thisObject._dataElement.posBox = null
			thisObject._containerElement.className+=""
		}
		
		this._groupElement.onmousedown = function(e)
		{
			if(window.event)
			{
				var target = window.event.srcElement;
				var pos = [window.event.clientX, window.event.clientY]
			}
			else
			{
				var target = e.target
				var pos = [e.clientX, e.clientY] 
			}
			while(target!=null)
			{
				if(target.tagName=="TD" && target.getAttribute("field")!=null)
				{
					break;
				}
				target = target.parentNode;
			}
			if(target==null) return
			var field = target.getAttribute("field")
			target = target.parentNode;
			target.setAttribute("field", field)
			target.setAttribute('pressed', true)
			target.className+=""
			
			var i = thisObject.groupsIndex[target.getAttribute("field")]
			
			var dragingPos = pos
			thisObject.dragingMode = null
			
			target.setCapture();
			target.setAttribute("dragging", true)
			target.onmousemove = function(e)
			{
				var i = thisObject.groupsIndex[this.getAttribute("field")]
				if(window.event)
				{
					var pos = [window.event.clientX, window.event.clientY] 
				}
				else
				{
					var pos = [e.clientX, e.clientY] 
				}
				if(thisObject.dragingMode == null)
				{
					if(Math.abs(dragingPos[0]-pos[0])>5 || Math.abs(dragingPos[1]-pos[1])>5)
					{
						thisObject.dragingMode = "move"
						if(thisObject._moveElement == null)
						{
							thisObject._crossElement = document.createElement("DIV");
							thisObject._crossElement.className = "listgroup_cross"
							thisObject._crossElement.style.display="none"
							thisObject._containerElement.appendChild(thisObject._crossElement)
							
							thisObject._arrowsElement = document.createElement("DIV");
							thisObject._arrowsElement.className = "listgroup_arrows"
							thisObject._arrowsElement.style.display="none"
							thisObject._containerElement.appendChild(thisObject._arrowsElement)
							
							thisObject._moveElement = document.createElement("DIV");
							thisObject._moveElement.className = "listgroup_movebar"
							thisObject._containerElement.appendChild(thisObject._moveElement)
						}
						else
						{
							thisObject._crossElement.style.display="none"
							thisObject._arrowsElement.style.display="none"
							thisObject._moveElement.style.display="block"
						}
			
						var size = 0
						this.dragingHeadAreas = new Array() 
						for(var j=0; j<thisObject.fields.length; j++)
						{
							var width = (j==thisObject.fields.length-1?thisObject._headElement.offsetWidth-size:thisObject.fields[j].width)
							if(j==0 && thisObject.fields.length>1)
							{
								width+=(thisObject._groupElements.length-1)*16;
							}
							var middle = Math.round(width/2)
							this.dragingHeadAreas.push([j, (j==0?-9999:size), size+middle, (j==0?size-1:size-3)])
							this.dragingHeadAreas.push([j+1, size+middle, (j==thisObject.fields.length-1?size+9999:size+4+width), (j==thisObject.fields.length-1?size+width:size+width+2)])
							size+=width+5
						}
	
						var size = 0;
						this.dragingPosDiff = [pos[0]-listGroupColminWidth, pos[1]-listGroupColminWidth]
						this.dragingGroupAreas = new Array() 
						for(var j=0; j<thisObject.groups.length; j++)
						{
							var width = (thisObject._groupElements[j].rows[0].cells[0].offsetWidth+35)
							var middle = Math.round(width/2)
							if(j!=i && j!=i+1)
							{
								this.dragingGroupAreas.push([j, (j==0?-9999:size+4), size+4+middle, (j==0?size+4:size+9)])
							}
							if(j!=i && j!=i-1)
							{
								this.dragingGroupAreas.push([j+1, size+4+middle, (j==thisObject.groups.length-1?size+9999:size+9+width), size+9+width])
							}
							size+=width
							if(i==(j+1))
							{
								this.dragingPosDiff = [pos[0]-(size+listGroupColminWidth), pos[1]-((j+1)*9+listGroupColminWidth)]
							}
						}
	
						thisObject._moveElement.style.top = pos[1]-this.dragingPosDiff[1]+"px"
						thisObject._moveElement.style.left = pos[0]-this.dragingPosDiff[0]+"px"
						thisObject._moveElement.style.width = (this.cells[0].offsetWidth+30)+"px"
						thisObject._moveElement.innerHTML = (thisObject.groups[i].label)
						
						thisObject._headElement
					}
					return
				}
				else if(thisObject.dragingMode == "move")
				{
					var l = (pos[0]-this.dragingPosDiff[0])
					var t = (pos[1]-this.dragingPosDiff[1])
					if(l < 0-thisObject._moveElement.offsetWidth
						|| l > thisObject._headElement.offsetWidth
						|| t < 0-thisObject._moveElement.offsetHeight
						|| t > thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
					)
					{
						thisObject._crossElement.style.left = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2 - 20)+"px"
						thisObject._crossElement.style.top = (pos[1]-this.dragingPosDiff[1] + thisObject._moveElement.offsetHeight/2 - 20)+"px"
						thisObject._crossElement.style.display = "block"
						
						thisObject._arrowsElement.style.display = "none"
					}
					else if(t >= thisObject._headElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._headElement.offsetWidth
					)
					{
						var find = false;
						var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
						for(var j=0; j<this.dragingHeadAreas.length; j++)
						{
							if(middle>=this.dragingHeadAreas[j][1] && middle<=this.dragingHeadAreas[j][2])
							{
								thisObject._arrowsElement.style.left = (this.dragingHeadAreas[j][3]-4)+"px"
								thisObject._arrowsElement.style.top = "";
								thisObject._arrowsElement.style.display = "block"
								find = true;
								break
							}
						}
						if(!find)
						{
							thisObject._arrowsElement.style.display = "none"
						}
						thisObject._crossElement.style.display = "none"
					}
					else if(thisObject._containerElement.getAttribute('groupbox') !=null
						&& t >= thisObject._groupElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._groupElement.offsetHeight + thisObject._groupElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._groupElement.offsetWidth
					)
					{
						if(thisObject.groups.length==0)
						{
							thisObject._arrowsElement.style.top = "1px"
							thisObject._arrowsElement.style.left = "4px"
							thisObject._arrowsElement.style.display = "block"
						}
						else
						{
							var find = false;
							var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
							for(var j=0; j<this.dragingGroupAreas.length; j++)
							{
								if(middle>=this.dragingGroupAreas[j][1] && middle<=this.dragingGroupAreas[j][2])
								{
									thisObject._arrowsElement.style.left = (this.dragingGroupAreas[j][3]-4)+"px"
									thisObject._arrowsElement.style.top = (this.dragingGroupAreas[j][0]*9-5)+(this.dragingGroupAreas[j][0]==0?4:0)+"px";
									thisObject._arrowsElement.style.display = "block"
									find = true;
									break
								}
							}
							if(!find)
							{
								thisObject._arrowsElement.style.display = "none"
							}
							thisObject._crossElement.style.display = "none"
						}
					}
					else
					{
						thisObject._crossElement.style.display = "none"
						thisObject._arrowsElement.style.display = "none"
					}
					thisObject._moveElement.style.left = l+"px"
					thisObject._moveElement.style.top = t+"px"
				}
			}
			target.onmouseup = function(e)
			{
				if(window.event)
				{
					var pos = [window.event.clientX, window.event.clientY] 
				}
				else
				{
					var pos = [e.clientX, e.clientY]
				}
				
				if(this.getAttribute('dragging') == null)
				{
					return
				}
				this.removeAttribute('dragging')
				this.releaseCapture();
	
				this.removeAttribute('pressed')
				this.className+=""
				this.onmousemove = null;
	
				if(thisObject.dragingMode=="move")
				{
					thisObject.dragingMode == null
					
					var i = thisObject.groupsIndex[this.getAttribute("field")]
					var l = (pos[0]-this.dragingPosDiff[0])
					var t = (pos[1]-this.dragingPosDiff[1])
					if(l < 0-thisObject._moveElement.offsetWidth
						|| l > thisObject._headElement.offsetWidth
						|| t < 0-thisObject._moveElement.offsetHeight
						|| t > thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
					)
					{
						thisObject.removeGroup(i)
					}
					else if(t >= thisObject._headElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._headElement.offsetHeight + thisObject._headElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._headElement.offsetWidth
					)
					{
						var find = -1;
						var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
						for(var j=0; j<this.dragingHeadAreas.length; j++)
						{
							if(middle>=this.dragingHeadAreas[j][1] && middle<=this.dragingHeadAreas[j][2])
							{
								find = this.dragingHeadAreas[j][0];
								break
							}
						}
						if(find!=-1)
						{
							thisObject.fieldGroup(i, find)
						}
					}
					else if(thisObject._containerElement.getAttribute('groupbox') !=null
						&& t >= thisObject._groupElement.offsetTop - thisObject._moveElement.offsetHeight
						&& t <= thisObject._groupElement.offsetHeight + thisObject._groupElement.offsetTop
						&& l > 0 - thisObject._moveElement.offsetWidth
						&& l <= thisObject._groupElement.offsetWidth
					)
					{
						if(thisObject.groups.length==0)
						{
							thisObject.groupField(i, 0)
						}
						else
						{
							var find = -1;
							var middle = (pos[0]-this.dragingPosDiff[0] + thisObject._moveElement.offsetWidth/2)
							for(var j=0; j<this.dragingGroupAreas.length; j++)
							{
								if(middle>=this.dragingGroupAreas[j][1] && middle<=this.dragingGroupAreas[j][2])
								{
									find = this.dragingGroupAreas[j][0];
									break
								}
							}
							if(find!=-1)
							{
								thisObject.moveGroup(i, find)
							}
						}
					}
					else
					{
					}
	
					thisObject._moveElement.style.display="none"
					thisObject._crossElement.style.display="none"
					thisObject._arrowsElement.style.display="none"
				}
			}
		}
	}
}




listGroup.prototype.sortDatas = function(fieldName)
{
	this.cache = new Array();
	this.drawed = new Array();
	this.selectedIndex = -1;
	this._selectElement.style.visibility="hidden"

	for(var j=0; j<this.fields.length; j++)
	{
		var field = this.fields[j]
		this._colsElementList[field.name].innerHTML='<div class="listgroup_field_data" style="top:'+(this.datasLength*listGroupItemHeight)+'px"></div>'
		this._colsElementList[field.name].removeAttribute("selected")
	}
	this._colsElementList[fieldName].setAttribute("selected", true)
	this._colsElement.className+=""
	
	var index = this.datasIndex
	var length = Math.ceil(this._dataElement.offsetHeight / listGroupItemHeight);
	
	var thisObject = this;
	
	for(var j=0; j<this.fields.length; j++)
	{
		var field = this.fields[j]
		this._headElement.childNodes[1+2*j].childNodes[0].removeAttribute("order")
		this._headElement.childNodes[1+2*j].className+=""
	}
	this._headElement.childNodes[1+2*this.fieldsIndex[fieldName]].childNodes[0].setAttribute("order", "loading")
	this._headElement.childNodes[1+2*this.fieldsIndex[fieldName]].className+=""
	
	ajax.sendAsync("./action/commun/listGroup.php5?action=sort&id="+this.id+"&field="+fieldName+"&index="+index+"&length="+length, function(datas)
	{
		var ch = null;
		eval('ch='+datas);
		for(var i=0; i<ch.length && i<ch.datas.length; i++)
		{
			thisObject.cache[ch.index + i] = ch.datas[i]
		}
		thisObject.drawDatas(thisObject.datasIndex, Math.ceil(thisObject._dataElement.offsetHeight / listGroupItemHeight));
		thisObject._headElement.childNodes[1+2*thisObject.fieldsIndex[fieldName]].childNodes[0].setAttribute("order", ch.order[0].sens)
		thisObject._headElement.childNodes[1+2*thisObject.fieldsIndex[fieldName]].className+=""
	})
}

listGroup.prototype.displayDatas = function()
{
	var start = this.datasIndex
	var length = Math.ceil(this._dataElement.offsetHeight / listGroupItemHeight)+1;
	var missing_start = -1 
	for(var i = start; i<start+length; i++)
	{
		if(this.cache[i] == null)
		{
			missing_start = i;
			break;
		}
	}
	if(missing_start<0)
	{
		this.drawDatas(start, length)
	}
	else
	{
		this.loadDatas(missing_start, length - missing_start + start)
	}
}

//charge les donn�es en ajax
listGroup.prototype.loadDatas = function(index, length, reinit)
{
	if(reinit == null) reinit = false
	//TODO verifier que les infos recu correspondent a la requete envoy�e (par ex : changement de groupement pendant la requete asynchrone)
	var thisObject = this;
	//TODO gestion de cache avec la variable data, pour eviter de faire deux fois la meme requete. tant que les groupements et tri ne change pas, la variable est utilisable
	ajax.sendAsync("./action/commun/listGroup.php5?action=load&id="+this.id+"&index="+index+"&length="+length, function(datas)
	{
		var ch = null;
		eval('ch='+datas);
		
		if(thisObject.datasLength != ch.datasLength)
		{
			thisObject.datasLength = ch.datasLength
			thisObject._innerScrollElement.style.height = (thisObject.datasLength*listGroupItemHeight)+"px"
			for(var i=0; i<thisObject.fields.length; i++)
			{
				thisObject._colsElementList[thisObject.fields[i].name].innerHTML='<div class="listgroup_field_data" style="visibility:hidden; top:'+(thisObject.datasLength*listGroupItemHeight)+'px"></div>'
			}
			for(var i=0; i<thisObject.groups.length; i++)
			{
				thisObject._colsElementList[thisObject.groups[i].name].innerHTML='<div class="listgroup_field_data" style="visibility:hidden; top:'+(thisObject.datasLength*listGroupItemHeight)+'px"></div>'
			}
			if(thisObject._innerScrollElement.offsetHeight > thisObject._scrollElement.offsetHeight)
			{
				thisObject._scrollElement.style.visibility="visible"
			}
		}
		else if(reinit)
		{
			for(var i=0; i<thisObject.fields.length; i++)
			{
				thisObject._colsElementList[thisObject.fields[i].name].innerHTML='<div class="listgroup_field_data" style="visibility:hidden; top:'+(thisObject.datasLength*listGroupItemHeight)+'px"></div>'
			}
			for(var i=0; i<thisObject.groups.length; i++)
			{
				thisObject._colsElementList[thisObject.groups[i].name].innerHTML='<div class="listgroup_field_data" style="visibility:hidden; top:'+(thisObject.datasLength*listGroupItemHeight)+'px"></div>'
			}
		}
		
		for(var i=0; i<ch.length && i<ch.datas.length; i++)
		{
			thisObject.cache[ch.index + i] = ch.datas[i]
			if(thisObject.selectedIndex == ch.index + i)
			{
				if(thisObject.onSelectChange != '')
				{
					var fct = eval(thisObject.onSelectChange)
					fct(thisObject.cache[thisObject.selectedIndex])
				}
			}
		}
		thisObject.drawDatas(index, length)
	})


	//TODO
	
	//recup�re les N prochaines �l�ments
	
	//TODO reorganiser les tableaux en cas de groupement
}

//TODO gestion de la pagination

//TODO filtre de recherche

listGroup.prototype.drawDatas = function(index, length)
{
	for(var i = index; i<index+length; i++)
	{
		if(this.cache[i] == null) break;
		if(this.drawed[i] != null) continue;
		var row = this.cache[i];
		for(var j=0; j<this.fields.length; j++)
		{
			var field = this.fields[j]
			this.drawed[i] = true
			var elem = document.createElement("DIV")
			elem.className = "listgroup_field_data"
			elem.style.top = (listGroupItemHeight*i)+"px"
			elem.innerHTML = row[field.data_field]
			this._colsElementList[field.name].appendChild(elem)
		}
		for(var j=0; j<this.groups.length; j++)
		{
			var field = this.groups[j]
			this.drawed[i] = true
			var elem = document.createElement("DIV")
			elem.className = "listgroup_field_data"
			elem.style.top = (listGroupItemHeight*i)+"px"
			elem.innerHTML = row[field.data_field]
			this._colsElementList[field.name].appendChild(elem)
		}
	}
}

listGroup.prototype.redraw = function()
{
	this.cache = new Array();
	this.drawed = new Array();
	this.selectedIndex = -1;
	this._selectElement.style.visibility="hidden"
	
	var index = this.datasIndex
	var length = Math.ceil(this._dataElement.offsetHeight / listGroupItemHeight);
	
	this.loadDatas(index, length, true)
}